﻿<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=11">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <meta name="renderer" content="webkit">
    <title>PNR提取</title>
</head>
<body>
<div id="charts" style="width:900px;height:300px;overflow-y:auto;">

</div>
<textarea id="rtinfo" style="width:900px;height:400px;" placeholder="输入RTPNR相关信息"></textarea>
<button id="btn_oper">提取PNR信息</button>
<button id="btn_oper_fee">提取代理费信息</button>
<button id="btn_oper_rtkt">RTKT</button>
<script src="jquery.js"></script>
<script>
    var _PnrInit = {
        getPnr: function (rtinfo) {
            var pnr = "", srcInfo = rtinfo;

            var isNext = false;
            var infoArr = rtinfo.split("1.")[1].split("\n")[0].split(" ");
            if (rtinfo.split("1.")[1].split("\n")[1].indexOf(".") == -1) {
                infoArr = (rtinfo.split("1.")[1].split("\n")[0] + " " + rtinfo.split("1.")[1].split("\n")[1]).split(" ");
            }
            for (var i in infoArr) {
                if (infoArr[i].length == 6 && infoArr[i].indexOf(".") == -1) {
                    pnr = infoArr[i];
                }
            }

            if (pnr.length == 0) {
                var content = rtinfo.split("\n")[0];
                if (content.indexOf("1.") == -1) {
                    content = rtinfo.split("\n")[1];
                }
                var regex = /\b[A-Za-z0-9]{6}\b/g;
                var pnrs = content.match(regex);

                if (pnrs == null || pnrs.length == 0) {
                    content = rtinfo.split("\n")[1];
                    pnrs = content.match(regex);
                }

                if (pnrs.length > 0) {
                    pnr = pnrs[0];
                }
                else {
                    pnr = "";
                }
            }

            return pnr;
        },
        getFare: function (rtinfo, pnr) {
            var fName = [], fCard = [], fTno = [], price = [], fare = [], ctcm = [],fGJ = [];
            var fNum = 1;
            var isGJ = false,isINF = false;
            var infoArr = [];
            if (rtinfo.split("1.")[1].split("\n")[0].indexOf(pnr) > -1) {
                infoArr = ("1." + rtinfo.split("1.")[1].split("\n")[0].split(pnr)[0]).split(".");
                if (rtinfo.split("1.")[1].split("\n")[0].indexOf(pnr) == -1) {
                    infoArr = ("1." + rtinfo.split("1.")[1].split("\n")[0]).split(".");
                }
            }
            else {
                infoArr = rtinfo.split(pnr)[0].replace(/\n/g,"").split(".");
            }
            //提取姓名
            for (var i in infoArr) {
                if (infoArr[i].length > 2) {
                    if (infoArr[i].indexOf(" ") > -1) {
                        fName.push({ name: infoArr[i].split(" ").slice(0, infoArr[i].split(" ").length - 1).join(" "), sign: "P" + fNum });
                    }
                    else {
                        fName.push({ name: infoArr[i], sign: "P" + fNum });
                    }
                    fNum++;
                }
            }
            infoArr = rtinfo.replace(/\n/g, " ").split("SSR");
            //提取婴儿
            for (var i in infoArr) {
                if (infoArr[i].length > 0 && infoArr[i].indexOf("INF(") > -1) {
                    var infs = infoArr[i].split("INF(")[0].split("/");
                    var infe = infoArr[i].split("INF(")[1].split("/");
                    fName.push({ name: infs[infs.length - 1].trim() + "INF(" + infe[0], sign: "INF" });
                    isINF = true;
                }
            }
            //提取证件号码及票号
            for (var i in infoArr) {
                //证件提取（身份证）
                if (infoArr[i].length > 0 && infoArr[i].indexOf("FOID") > -1) {
                    fGJ.push({ isGj: false, sign: infoArr[i].split("NI")[1].split("/")[1].split(" ")[0] });
                    fCard.push({ card: infoArr[i].split("NI")[1].split("/")[0], sign: infoArr[i].split("NI")[1].split("/")[1].split(" ")[0] });
                }
                //婴儿出生日期
                if (infoArr[i].length > 0 && infoArr[i].indexOf("INFT") > -1) {
                    var infdate = infoArr[i].split("/P")[0].split(" ");
                    fGJ.push({ isGj: false, sign: "INF" });
                    fCard.push({ card: infdate[infdate.length-1].trim(), sign: "INF" });
                }
                //证件提取（护照）
                if (infoArr[i].length > 0 && infoArr[i].indexOf("DOCS") > -1) {
                    isGJ = true;
                    var temp = infoArr[i].replace(/\n/g, " ").replace(/ +/g, " ").split(" ");
                    var tempStr = "";
                    for (var j in temp) {
                        if (temp[j].length > 4 && (temp[j].indexOf("/") > -1 || temp[j].indexOf(".") > -1)) {
                            if (temp[j].indexOf(".") > -1) {
                                break;
                            }
                            tempStr += temp[j];
                        }
                    }
                    fGJ.push({ isGj: true, sign: tempStr.split("/")[tempStr.split("/").length - 1] });
                    fCard.push({ card: tempStr.split("/").slice(0, 7), sign:tempStr.split("/")[tempStr.split("/").length-1] });
                    /*
                    for (var j in itemArray) {
                        if (itemArray[j].indexOf("/") > -1) {
                            var tempSign = itemArray[j].split("/")[itemArray[j].split("/").length - 1];
                            fCard.push({ card: itemArray[j].split("/").slice(1, itemArray[j].split("/").length - 1).join(" "), sign: tempSign });
                        }
                    }
                    */
                }
                //票号提取
                if (infoArr[i].length > 0 && infoArr[i].indexOf("TKNE") > -1) {
                    for (var j in infoArr[i].split(" ")) {
                        if (infoArr[i].split(" ")[j].indexOf("/") > -1) {
                            if (infoArr[i].split(" ")[j].split("/")[0].indexOf("INF") > -1) {
                                fTno.push({ no: infoArr[i].split(" ")[j].split("/")[0], sign: "INF" });
                            }
                            else {
                                fTno.push({ no: infoArr[i].split(" ")[j].split("/")[0], sign: infoArr[i].split(" ")[j].split("/")[2] });
                            }
                        }
                    }

                }
            }

            //CTCM项提取
            if (isGJ) {
                infoArr = rtinfo.split("CTCM");
                for (var i in infoArr) {
                    if (i == 0) { continue; }
                    if (infoArr[i].length > 0 && infoArr[i].indexOf("/P") > -1) {
                        var tempCt = infoArr[i].split("\n")[0].split(" ");
                        for (var ci in tempCt) {
                            if (tempCt[ci].indexOf("/P") > -1) {
                                ctcm.push({ mobile: tempCt[ci].split("/")[0], sign: tempCt[ci].split("/")[1] });
                            }
                        }

                    }
                }
            }
            else {
                infoArr = rtinfo.replace(/\n/g, " ").split("CTCM");
                for (var i in infoArr) {
                    if (i == 0) { continue; }
                    if (infoArr[i].length > 0 && infoArr[i].indexOf("/P") > -1) {
                        ctcm.push({ mobile: infoArr[i].split(" ")[0].split("/")[0], sign: infoArr[i].split(" ")[0].split("/")[1] });
                    }
                }
            }


            //提取价格
            if (rtinfo.indexOf("FN/") > -1) {
                var ptemp = [], itemp = [];
                var trInfo = rtinfo.replace(/ /g, "");
                infoArr = trInfo.replace(/\nACNY/g, "ACNY").split("FN/");//rtinfo.replace(/\n/g, " ").split("FN/");
                for (var i in infoArr) {
                    if (infoArr[i].length > 0 && (infoArr[i].indexOf("FCNY") > -1 || infoArr[i].indexOf("ECNY") > -1)) {
                        var FCNY = "0", CN = "0", YQ = "0", TAX = "0", SIGN = "";
                        if (infoArr[i].indexOf("\n") > -1) {
                            itemp = infoArr[i].split("\n")[0].split("/");
                        }
                        else {
                            itemp = infoArr[i].split("/");
                        }
                        for (var j in itemp) {
                            var lastTwo = itemp[j].substr(itemp[j].length - 2, 2);
                            if (itemp[j].indexOf("FCNY") > -1 || itemp[j].indexOf("ECNY") > -1) {
                                if (itemp[j].indexOf("FCNY") > -1){
                                    FCNY = itemp[j].replace("FCNY", "").split(".")[0].replace(/\s/g, "");
                                }
                                else {
                                    FCNY = itemp[j].replace("ECNY", "").split(".")[0].replace(/\s/g, "");
                                }
                            }
                            if (itemp[j].indexOf("TCNY") > -1 && lastTwo.indexOf("CN") > -1) {
                                CN = itemp[j].replace("TCNY", "").split(".")[0].replace(/\s/g, "");
                            }
                            if (itemp[j].indexOf("TCNY") > -1 && lastTwo.indexOf("YQ") > -1) {
                                YQ = itemp[j].replace("TCNY", "").split(".")[0].replace(/\s/g, "");
                            }
                            /*
                            if (itemp[j].indexOf("TCNY") > -1 && (lastTwo.indexOf("XT") > -1 || lastTwo.indexOf("XF") > -1)) {
                                TAX = itemp[j].replace("TCNY", "").split(".")[0].replace(/\s/g, "");
                            }
                            */
                            if (itemp[j].indexOf("XCNY") > -1) {
                                TAX = itemp[j].replace("XCNY", "").split(".")[0].replace(/\s/g, "");
                            }
                            //if (/^[P][0-9]*.[+]./.test(itemp[j])) {
                            if (/^[P][0-9]*/.test(itemp[j])) {
                                SIGN = itemp[j].split(" ")[0];
                            }
                        }
                        price.push({ FCNY: FCNY, CN: CN, YQ: YQ, TAX: TAX, SIGN: SIGN });
                    }
                }
            }
            //整合信息
            for (var i in fName) {
                var name = fName[i].name, card = "", no = "", fcny = "", cn = "", yq = "", tax = "", mobile = "", isGJ = false;
                for (var j in fGJ) {
                    if (fGJ[j].sign == fName[i].sign) {
                        isGJ = fGJ[j].isGj;
                        break;
                    }
                }
                for (var j in fCard) {
                    if (fCard[j].sign == fName[i].sign) {
                        card = fCard[j].card;
                        break;
                    }
                }
                for (var j in fTno) {
                    if (fTno[j].sign == fName[i].sign) {
                        no = fTno[j].no;
                        break;
                    }
                }
                if (ctcm.length > 0) {
                    for (var j in ctcm) {
                        if (ctcm[j].sign == fName[i].sign) {
                            mobile = ctcm[j].mobile;
                            break;
                        }
                    }
                    if (mobile.length == 0) {
                        mobile = ctcm[0].mobile;
                    }
                }

                if (price.length == 1) {
                    fcny = price[0].FCNY, cn = price[0].CN, yq = price[0].YQ, tax = price[0].TAX;
                }
                else {
                    for (var j in price) {
                        if (price[j].SIGN == fName[i].sign) {
                            fcny = price[j].FCNY, cn = price[j].CN, yq = price[j].YQ, tax = price[j].TAX;
                            break;
                        }
                    }
                    if (fcny == "") {
                        for (var j in price) {
                            if (price[j].SIGN == "") {
                                fcny = price[j].FCNY, cn = price[j].CN, yq = price[j].YQ, tax = price[j].TAX;
                                break;
                            }
                        }
                    }
                }
                if (isGJ) {
                    if (name.indexOf("INF") == -1) {
                        fare.push({ ftype: 1, name: name, card: card, no: no, fcny: fcny, cn: cn, yq: yq, tax: tax, mobile: mobile });
                    }
                    else {
                        fare.push({ ftype: 2, name: name, card: card, no: no, fcny: fcny, cn: cn, yq: yq, tax: tax, mobile: mobile });
                    }
                }
                else {
                    if (name.indexOf("INF") == -1) {
                        fare.push({ ftype: 0, name: name, card: card, no: no, fcny: fcny, cn: cn, yq: yq, tax: tax, mobile: mobile });
                    }
                    else{
                        fare.push({ ftype: 2, name: name, card: card, no: no, fcny: fcny, cn: cn, yq: yq, tax: tax, mobile: mobile });
                    }
                }
            }

            return fare;
        },
        getFliht: function (rtinfo, pnr) {
            var fliht = [];
            var pnrNum = rtinfo.split(pnr).length;
            var flihtS = rtinfo.split(pnr)[1].split(".");
            var isGJ = false;
            if (rtinfo.indexOf("SSR DOCS") > -1) {
                isGJ = true;
            }
            if (pnrNum > 2) {
                flihtS = rtinfo.split(pnr)[2].split(".");
            }
            for (var i in flihtS) {
                var tempArray = flihtS[i].replace("/ +/g", " ").split("\n")[0].split(" ");
                var itemArray = $.grep(tempArray, function (value) {
                    return value && value.toString().trim() !== "";
                });
                if (itemArray.length > 7) {
                    if ((itemArray[0].length == 6 || itemArray[0].length == 5) && /^[a-zA-Z0-9]{2,3}[0-9]{3}$/.test(itemArray[0])) {
                        if (itemArray.length > 9 && isGJ) {
                            fliht.push(itemArray.slice(0, 10));
                        }
                        else {
                            //处理特殊情况，日期和城市在一起
                            if (itemArray[2].length >= 13) {
                                fliht.push(itemArray.slice(0, 1));
                                fliht.push(itemArray[2].substr(0, 7));
                                fliht.push(itemArray[2].substr(itemArray[2].length - 6, itemArray[2].length - 1))
                                fliht.push(itemArray.slice(3, 8));
                            }
                            else {
                                if (itemArray.length >= 9) {
                                    if (itemArray[8].indexOf("--") > -1 && itemArray[8].length > 2) {
                                        var tarr = itemArray.slice(0, 8);
                                        tarr.push(itemArray[8].split("--")[0] == "" ? "--" : itemArray[8].split("--")[0]);
                                        tarr.push(itemArray[8].split("--")[1] == "" ? "--" : itemArray[8].split("--")[1]);
                                        fliht.push(tarr);
                                    }
                                    else {
                                        fliht.push(itemArray.slice(0, 9));
                                    }
                                }
                                else {
                                    fliht.push(itemArray.slice(0, 8));
                                }
                            }


                        }
                    }
                }
            }

            return fliht;
        },
        getRtktInfo: function (rtktInfo) {
            var rtkt = [];
            var officeNo = "",priceCode = "",uatp = "";
            var arr = rtktInfo.replace("/ +/g", " ").replace(/\\r\\n/g,"\n").split("\n");
            for (var ri = 0; ri < arr.length; ri++) {

                var arrTemp = $.grep(arr[ri].split(" "), function (value) {
                    return value + "," && value.toString().trim() !== "";
                });

                var tempStr = arrTemp.join(",");

                if (tempStr.indexOf("/") > 0 && officeNo.length == 0) {
                    try {
                        var officeNoStr = tempStr.split("/")[tempStr.split("/").length-1].replace(/ /g, "");
                        officeNo = officeNoStr.substr(officeNoStr.length - 6, 6);
                        if (/^[a-zA-Z]{3}[0-9]{3}$/.test(officeNo.replace(/ /g, ""))) {
                            rtkt.push({ "officeNo": officeNo });
                            rtkt.push({ "printNo": arr[ri + 1].replace(/ /g, "").replace("DEV-", "").trim() });
                        }
                        else {
                            officeNo = "";
                        }
                    }
                    catch(e){
                        rtkt.push({ "officeNo": "" });
                        rtkt.push({ "printNo": ""});
                    }

                }
                if (ri == arr.length - 1) {
                    for (var typei = ri; typei > -10; typei--) {
                        if (arr[typei].replace(/ /g, "").trim().length > 0) {
                            var typeTemp = arr[typei].split(" ");
                            for (var tpi = typeTemp.length - 1; tpi >= 0; tpi--) {
                                if (typeTemp[tpi].length > 0) {
                                    rtkt.push({ "ticketType": typeTemp[tpi].replace(/ /g, "").trim() });
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }

                var tempVoid = arrTemp[arrTemp.length - 1];
                if (typeof(tempVoid) != "undefined" && tempVoid.indexOf("VOID") > -1 && priceCode.length == 0) {
                    arrTemp = $.grep(arr[ri-1].split(" "), function (value) {
                        return value && value.toString().trim() !== "";
                    });
                    if (arrTemp.length < 2) {
                        arrTemp = $.grep(arr[ri - 2].split(" "), function (value) {
                            return value && value.toString().trim() !== "";
                        });
                    }
                    try{
                        priceCode = arrTemp[arrTemp.length - 2].trimStart();
                        if (priceCode.substr(0, 2) == "OK") {
                            priceCode = priceCode.substr(2, priceCode.length - 2);
                            rtkt.push({ "priceCode": priceCode })
                        }


                        var baggage = arrTemp[arrTemp.length - 1].replace(/ /g, "");
                        if (baggage.length >= 3) {
                            baggage = baggage.substr(baggage.length - 3, 3);
                            rtkt.push({ "baggage": baggage })
                        }
                    }
                    catch (e) {
                        rtkt.push({ "priceCode": "" })
                    }

                }

                if (tempStr.indexOf("CC,TP") > -1) {
                    uatp = "TP" + tempStr.split("CC,TP")[1].split(" ")[0];
                }
                if (tempStr.indexOf("CC,UP") > -1) {
                    uatp = "UP" + tempStr.split("CC,UP")[1].split(" ")[0];
                }
            }

            var fee = 0;
            var itemArray = rtktInfo.replace("/ +/g", " ").replace(/\n/g, " ").replace(/CNY0.00/g, "CNY").split(" ");
            var arr = $.grep(itemArray, function (value) {
                return value && value.toString().trim() !== "";
            });
            for (var ri = arr.length - 1; ri >= 0; ri--) {
                if (arr[ri].indexOf("CNY") > -1) {
                    if (arr[ri] == "CNY") {
                        fee = arr[ri + 2];
                        break;
                    }
                    else {
                        fee = arr[ri + 1];
                        break;
                    }
                }
            }
            if (!fee) {
                fee = 0;
            }
            rtkt.push({ "agentFee": fee });
            rtkt.push({ "uatp": uatp });
            return rtkt;
        },
        getAgentFee: function (rtktInfo) {
            var fee;
            var itemArray = rtktInfo.replace("/ +/g", " ").replace(/\n/g, " ").replace(/CNY0.00/g, "CNY").split(" ");
            var arr = $.grep(itemArray, function (value) {
                return value && value.toString().trim() !== "";
            });
            for (var ri = arr.length - 1; ri >= 0; ri--)
            {
                if (arr[ri].indexOf("CNY") > -1)
                {
                    if (arr[ri] == "CNY")
                    {
                        fee = arr[ri + 2];
                        break;
                    }
                    else
                    {
                        fee = arr[ri + 1];
                        break;
                    }
                }
            }
            if (!isNaN(fee)) {
                return fee;
            }
            else {
                return "";
            }
        },
        getOfficeNo: function (rtinfo) {
            var itemArray = rtinfo.replace(/\n/g, " ").split(".");
            var arr = $.grep(itemArray, function (value) {
                return value && value.toString().trim() !== "";
            });
            if (arr[arr.length - 1].replace(/ /g, "").length == 6) {
                if (/^[a-zA-Z]{3}[0-9]{3}$/.test(arr[arr.length - 1].replace(/ /g, ""))) {
                    return arr[arr.length - 1].replace(/ /g, "")
                }
            }
            return "";
        },
        getRmkInfo: function (rtinfo) {
            var itemArray = rtinfo.split("\n");
            var arr = $.grep(itemArray, function (value) {
                return value && value.toString().trim() !== "";
            });
            var rmk = [];
            for (var ri = 0; ri < arr.length; ri++) {
                if (arr[ri].length > 0 && arr[ri].indexOf(".RMK") > -1) {
                    rmk.push("RMK " + arr[ri].split("RMK")[1]);
                }
            }
            if (rmk.length > 0) {
                return rmk.join("|");
            }
            else {
                return "";
            }
        }
    }

    $("#btn_oper_fee").click(function () {
        $("#charts").html("");
        //获取RTPNR信息，可以采用其他方式获取
        var rtinfo = $("#rtinfo").val();
        var fee = _PnrInit.getAgentFee(rtinfo)
        $("#charts").append("<br/><br/>代理费:" + fee);
    });

    $("#btn_oper_rtkt").click(function () {
        $("#charts").html("");
        var rtinfo = $("#rtinfo").val();
        var rtkt = _PnrInit.getRtktInfo(rtinfo);
        //rtkt:[{"officeNo":"TYN105"},{"printNo":"DEV-03"},{"priceCode":"V/SWX"},{"ticketType":"BSP"},{"agentFee":"60"}]
        $("#charts").append("<br/><br/>officeNo:" + rtkt[0]["officeNo"]);
        $("#charts").append(",printNo:" + rtkt[1]["printNo"]);
        $("#charts").append(",priceCode:" + rtkt[2]["priceCode"]);
        $("#charts").append(",baggage:" + rtkt[3]["baggage"]);
        $("#charts").append(",ticketType:" + rtkt[4]["ticketType"]);
        $("#charts").append(",agentFee:" + rtkt[5]["agentFee"]);
        $("#charts").append(",cc:" + rtkt[6]["uatp"]);
    })

    $("#btn_oper").click(function () {
        $("#charts").html("");
        //获取RTPNR信息，可以采用其他方式获取
        var rtinfo = $("#rtinfo").val();

        //提取PNR
        var pnr = _PnrInit.getPnr(rtinfo);

        //打印测试
        $("#charts").append("<br/><br/>pnr:" + pnr);

        //提取officeNo
        var officeNo = _PnrInit.getOfficeNo(rtinfo);

        //打印测试
        $("#charts").append("<br/><br/>officeNo:" + officeNo);


        //提取航班信息
        /*
            返回格式：数组
            返回样例：[[MU2409,N,SA07SEP,TYNHET,RR2,1510,1615,E,T2]] 一段行程
            返回样例：[[MU2409,N,SA07SEP,TYNHET,RR2,1510,1615,E,T2],[MU2409,N,SA07SEP,TYNHET,RR2,1510,1615,E,T2]] 两段行程
            字段说明：航班号,仓位,航班日期,出发地三字码+目的地三字码,当前状态,起飞时间,到达时间,机场航站楼
        */
        var fliht = _PnrInit.getFliht(rtinfo, pnr);

        //打印测试
        $("#charts").append("<br/><br/>航班信息：");
        for (var i in fliht) {
            $("#charts").append("<br/>" + fliht[i]);
        }

        //提取乘客信息
        /*
            返回格式：数组 (ftype为类型，0代表身份证1代表护照)
            返回样例：身份证[{ftype:0, name: 姓名, card: 证件号码, no: 票号, fcny: 票价, cn: 机建, yq: 燃油, tax: 税 },{ name: 姓名, card: 证件号码, no: 票号, fcny: 票价, cn: 机建, yq: 燃油, tax: 税,mobile:CTCM项 }]
            返回样例：其他证件  [{ftype:1, name: 姓名, card: [证件类型,发证国家,证件号码,国籍,出生日期,性别,证件有效期], no: 票号, fcny: 票价, cn: 机建, yq: 燃油, tax: 税 },{ name: 姓名, card: 证件号码, no: 票号, fcny: 票价, cn: 机建, yq: 燃油, tax: 税,mobile:CTCM项 }]
            证件说明：证件类型对照（P-护照    M-军官证     G-海员证     A-通行证      F-外国人永久居留证  C-驻华外交人员证   I-其它证件）
            字段说明：票号及票价等可能为空，根据pnr当前状态及信息确定，tax为税（国际票）
        */
        var fare = _PnrInit.getFare(rtinfo, pnr);

        //打印测试
        for (var i in fare) {
            $("#charts").append("<br/>第" + i + "个乘客：");
            Object.keys(fare[i]).forEach(function (key) {
                $("#charts").append("," + fare[i][key]);
            });
        }

        //提取RMK项
        var rmk = _PnrInit.getRmkInfo(rtinfo);
        $("#charts").append("<br/>RMK项：" + rmk);
    });
</script>

</body>
</html>